// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;

namespace SnapObjects.Data
{
    internal abstract class SqlUpdateStatementParser : SqlQueryStatementParser
    {
        public SqlUpdateStatementParser(
            ISqlStatementFactory factory, ISqlGenerationHelper helper) : base(factory, helper)
        {
        }

        public override SqlStatement ParseStatement(ISqlTokenizer tokenizer, bool isClause)
        {
            _isClause = isClause;

            var update = new SqlUpdateStatement();

            while (tokenizer.MoveNext())
            {
                if (tokenizer.Current is SqlKeywordToken token)
                {
                    if (token.Keyword == SqlKeywords.UPDATE)
                    {
                        this.ParseUpdate(tokenizer, update);

                        this.ParseSet(tokenizer, update);

                        if (tokenizer.Current is SqlKeywordToken key
                            && key.Keyword == SqlKeywords.FROM)
                        {
                            this.ParseFrom(tokenizer, update);
                        }

                        this.ParseWhere(tokenizer, update);
                    }
                    else
                    {
                        throw new InvalidCastException(tokenizer.Current.Text);
                    }
                }
                else
                {
                    throw new InvalidCastException(tokenizer.Current.Text);
                }
            }

            return update;
        }

        protected virtual bool ParseUpdate(ISqlTokenizer tokenizer, SqlUpdateStatement statement)
        {
            var result = false;

            while (tokenizer.MoveNext())
            {
                if (tokenizer.Current is SqlKeywordToken key
                    && key.Keyword == SqlKeywords.SET)
                {
                    result = true;

                    break;
                }
                else
                {
                    if (!String.IsNullOrWhiteSpace(tokenizer.Current.Text))
                    {
                        statement.Table.Add(tokenizer.Current);
                    }
                }
            }

            return result;
        }

        protected virtual bool ParseSet(ISqlTokenizer tokenizer, SqlUpdateStatement statement)
        {
            var result = false;

            while (tokenizer.MoveNext())
            {
                if (tokenizer.Current is SqlKeywordToken key
                    && (key.Keyword == SqlKeywords.FROM
                    || key.Keyword == SqlKeywords.WHERE))
                {
                    result = true;

                    break;
                }
                else
                {
                    if (!String.IsNullOrWhiteSpace(tokenizer.Current.Text))
                    {
                        statement.Set.Add(tokenizer.Current);
                    }
                }
            }

            return result;
        }
    }
}
